﻿#include "Experiment/ExperimentThread.h"

ExperimentThread::ExperimentThread()
{
}

ExperimentThread& ExperimentThread::I(){
    static ExperimentThread instance;
    return instance;
}

void ExperimentThread::run()
{
    UdpClient *udpClient;
    udpClient=UdpClient::getInstance();

    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql;

    if(StaticProperties::stepStartTime.isNull()){
        msecs=0;
    }
    else{
        msecs = QDateTime::currentDateTime().toMSecsSinceEpoch() - StaticProperties::stepStartTime.toMSecsSinceEpoch();
    }

    StaticProperties::stepStartTime=QDateTime::currentDateTime();

    CommonHelper::Common().staticUseTime(1,QString::number(msecs/1000));

    QString checkInfo=routineVerification();
    if(!checkInfo.isEmpty()){
        QMLSignal::I().emitSendErrorMsg(checkInfo,"否",QString::number(StaticProperties::currentExpModule),0);
        return;
    }

    sql=QString("Update ExperimentInfo set ExpStep='%1'").arg(QString::number(StaticProperties::expStep));
    query.exec(sql);

    QVariantMap map= StaticProperties::expSendList[StaticProperties::expStep];
    int currentModule=map["Module"].toInt();
    if(StaticProperties::expStep==StaticProperties::expStartStep)//第一步(改变状态,后续处理)
    {
        StaticProperties::currentExpModule=currentModule;
        QMLSignal::I().emitModuleCurrent(StaticProperties::currentExpModule);

        StaticProperties::expLogList[currentModule-1][StaticProperties::expStep]["Status"]="进行中";

        sql=QString("Update ReportDetail set status='进行中' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%1'").arg(QString::number(StaticProperties::expStep));
        query.exec(sql);
        StaticProperties::maxStep=StaticProperties::expSendList.lastKey();
    }
    else if(StaticProperties::maxStep<StaticProperties::expStep)//最后一步
    {
        QVariantMap map= StaticProperties::expSendList[StaticProperties::expStep-1];
        if(StaticProperties::currentExpType==0){
            if(StaticProperties::softType==1)
            {
                StaticProperties::expLogList[2][map["Step"].toInt()]["Status"]="完成";
                StaticProperties::expLogList[2][map["Step"].toInt()]["FinishTime"]=CommonHelper::Common().GetTimeStr();
                StaticProperties::expLogList[2][map["Step"].toInt()]["Time"]=QString::number(msecs);
            }
            else
            {
                StaticProperties::expLogList[3][map["Step"].toInt()]["Status"]="完成";
                StaticProperties::expLogList[3][map["Step"].toInt()]["FinishTime"]=CommonHelper::Common().GetTimeStr();
                StaticProperties::expLogList[3][map["Step"].toInt()]["Time"]=QString::number(msecs);
            }
        }
        else
        {
            StaticProperties::expLogList[StaticProperties::currentExpType-1][map["Step"].toInt()]["Status"]="完成";
            StaticProperties::expLogList[StaticProperties::currentExpType-1][map["Step"].toInt()]["FinishTime"]=CommonHelper::Common().GetTimeStr();
            StaticProperties::expLogList[StaticProperties::currentExpType-1][map["Step"].toInt()]["Time"]=QString::number(msecs);
        }
        sql=QString("Update ReportDetail set status='完成',FinishTime='%1',Time='%2' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%3'").arg(CommonHelper::Common().GetTimeStr(),QString::number(msecs),map["Step"].toString());
        query.exec(sql);

        QMLSignal::I().emitRefExperimentLog(StaticProperties::currentStep);     // 发信号通知前端
        udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().stopExperiment()));
        return;
    }
    else//其他步骤处理
    {
        if(currentModule!=StaticProperties::currentExpModule)//模块动作全部完成跳转,联动跳转
        {
            if(StaticProperties::currentExpModule==4)//联动情况下的模块跳转
            {
                QVariantMap finishMap=StaticProperties::expSendList[StaticProperties::expStep-1];
                if(StaticProperties::expLogList[3][finishMap["Step"].toInt()]["Status"]!="故障"){
                    StaticProperties::expLogList[3][finishMap["Step"].toInt()]["Status"]="完成";
                    StaticProperties::expLogList[3][finishMap["Step"].toInt()]["FinishTime"]=CommonHelper::Common().GetTimeStr();
                    StaticProperties::expLogList[3][finishMap["Step"].toInt()]["Time"]=QString::number(msecs);
                    sql=QString("Update ReportDetail set status='完成',FinishTime='%1',Time='%2' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%3'").arg(CommonHelper::Common().GetTimeStr(),QString::number(msecs),finishMap["Step"].toString());
                    query.exec(sql);
                }


                unionTime+=msecs;
                isUnion=false;

                if(StaticProperties::expLogList[2].contains(initialUnionStep)){
                    StaticProperties::expLogList[2][initialUnionStep]["Status"]="完成";
                    StaticProperties::expLogList[2][initialUnionStep]["FinishTime"]=CommonHelper::Common().GetTimeStr();
                    StaticProperties::expLogList[2][initialUnionStep]["Time"]=QString::number(unionTime);

                    sql=QString("Update ReportDetail set status='完成',FinishTime='%1',Time='%2' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%3'").arg(CommonHelper::Common().GetTimeStr(),QString::number(msecs),QString::number(initialUnionStep));
                    query.exec(sql);
                }

                StaticProperties::expLogList[2][map["Step"].toInt()]["Status"]="进行中";
                sql=QString("Update ReportDetail set status='进行中' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%1'").arg(map["Step"].toString());
                query.exec(sql);

                StaticProperties::currentExpModule=3;
                QMLSignal::I().emitModuleCurrent(StaticProperties::currentExpModule);
            }
            else//正常步骤完成的模块跳转
            {
                if(StaticProperties::expStartStepList[currentModule-1]>1){
                    StaticProperties::expStep=StaticProperties::expStep+StaticProperties::expStartStepList[currentModule-1]-1;
                    map= StaticProperties::expSendList[StaticProperties::expStep];
                    currentModule=map["Module"].toInt();
                }

                StaticProperties::expLogList[currentModule-1][map["Step"].toInt()]["Status"]="进行中";
                sql=QString("Update ReportDetail set status='进行中' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%1'").arg(map["Step"].toString());
                query.exec(sql);

                QMLSignal::I().emitModuleFinish(StaticProperties::currentExpModule);
                StaticProperties::currentExpModule=currentModule;
                QMLSignal::I().emitModuleCurrent(StaticProperties::currentExpModule);

                if(StaticProperties::expLogList[currentModule-2][StaticProperties::expLogList[currentModule-2].lastKey()]["Status"]!="故障"){
                    StaticProperties::expLogList[currentModule-2][StaticProperties::expLogList[currentModule-2].lastKey()]["Status"]="完成";
                    StaticProperties::expLogList[currentModule-2][StaticProperties::expLogList[currentModule-2].lastKey()]["FinishTime"]=CommonHelper::Common().GetTimeStr();
                    StaticProperties::expLogList[currentModule-2][StaticProperties::expLogList[currentModule-2].lastKey()]["Time"]=QString::number(msecs);

                    sql=QString("Update ReportDetail set status='完成',FinishTime='%1',Time='%2' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%3'").arg(CommonHelper::Common().GetTimeStr(),QString::number(msecs),QString::number(StaticProperties::expLogList[0].lastKey()));
                    query.exec(sql);
                }
            }
        }
        else{
            if(map["Type"]=="4"){
                QVariantMap lastMap= StaticProperties::expSendList[StaticProperties::expStep-1];
                if(lastMap["Type"]!=7 && StaticProperties::expLogList[3].contains(lastMap["Step"].toInt())&& StaticProperties::expLogList[3][lastMap["Step"].toInt()]["Status"]!="故障"){
                    StaticProperties::expLogList[3][lastMap["Step"].toInt()]["Status"]="完成";
                    StaticProperties::expLogList[3][lastMap["Step"].toInt()]["FinishTime"]=CommonHelper::Common().GetTimeStr();
                    StaticProperties::expLogList[3][lastMap["Step"].toInt()]["Time"]=QString::number(msecs);

                    sql=QString("Update ReportDetail set status='完成',FinishTime='%1',Time='%2' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%3'").arg(CommonHelper::Common().GetTimeStr(),QString::number(msecs),lastMap["Step"].toString());
                    query.exec(sql);
                }
                StaticProperties::expLogList[3][map["Step"].toInt()]["Status"]="检测中";
                sql=QString("Update ReportDetail set status='检测中' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%1'").arg(map["Step"].toString());
                query.exec(sql);
            }
            else{

                StaticProperties::expLogList[currentModule-1][map["Step"].toInt()]["Status"]="进行中";
                sql=QString("Update ReportDetail set status='进行中' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%1'").arg(map["Step"].toString());
                query.exec(sql);

                QVariantMap finishMap=StaticProperties::expSendList[StaticProperties::expStep-1];
                if(finishMap["Type"]!=8 && StaticProperties::expLogList[currentModule-1].contains(finishMap["Step"].toInt())&& StaticProperties::expLogList[currentModule-1][finishMap["Step"].toInt()]["Status"]!="故障"){
                    StaticProperties::expLogList[currentModule-1][finishMap["Step"].toInt()]["Status"]="完成";
                    StaticProperties::expLogList[currentModule-1][finishMap["Step"].toInt()]["FinishTime"]=CommonHelper::Common().GetTimeStr();
                    StaticProperties::expLogList[currentModule-1][finishMap["Step"].toInt()]["Time"]=QString::number(msecs);

                    sql=QString("Update ReportDetail set status='完成',FinishTime='%1',Time='%2' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%3'").arg(CommonHelper::Common().GetTimeStr(),QString::number(msecs),finishMap["Step"].toString());
                    query.exec(sql);
                    if(currentModule==4){
                        if(isUnion){
                            unionTime+=msecs;
                            QString sql=QString("Update ExperimentInfo set unionTime='%1', unionStep='%2'").arg(QString::number(unionTime) ,QString::number(initialUnionStep));
                            query.exec(sql);
                        }
                        if(isCircle){
                            circleTime+=msecs;
                            QString sql=QString("Update ExperimentInfo set circleTime='%1'").arg(QString::number(circleTime));
                            query.exec(sql);
                        }
                    }
                }
            }
        }
    }

    if(!specialStepVerification())
    {
        return;
    }

    stepProcessing(map);
}

void ExperimentThread::stepProcessing(QVariantMap map){
    UdpClient *udpClient;
    udpClient=UdpClient::getInstance();

    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql;

    // map["Type"];
    //0 正常执行(Info发送指令) 1循环(开始循环,结束循环) 2 跳过("") 3等待(等待时长) 4检测器 5联动 6暂停 7同步注射器
    if(map["Type"]=="0")
    {
        specialStepExecute();
        QString sendInfo= map["Info"].toString();
        udpClient->ClientSendingData(CommonHelper::Common().GetSendData(sendInfo));
        StaticProperties::currentStep=map["Step"].toInt();
        QMLSignal::I().emitRefExperimentLog(StaticProperties::currentStep);     // 发信号通知前端
    }
    else if(map["Type"]=="1")//只有纯化有循环
    {
        if(map["Info"].toString()=="完成")
        {
            refPurifyingExpLog(map["Step"].toInt(),"完成",circleTime);
            isCircle=false;
            sql="Update ExperimentInfo set isCircle='false'";
            query.exec(sql);
        }
        else
        {
            isCircle=true;
            sql="Update ExperimentInfo set isCircle='true'";
            query.exec(sql);
            refPurifyingExpLog(map["Step"].toInt(),map["Info"].toString());
        }

        if(StaticProperties::expStep>1){
            QVariantMap finishMap=StaticProperties::expSendList[StaticProperties::expStep-1];
            if( StaticProperties::expLogList[3][finishMap["Step"].toInt()]["Status"]!="完成"){
                refPurifyingExpLog(finishMap["Step"].toInt(),"完成");
            }
        }

        QVariantMap nextMap= StaticProperties::expSendList[StaticProperties::expStep+1];
        if(nextMap["Type"]=="0")
        {
            StaticProperties::stepStartTime=QDateTime::currentDateTime();
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(nextMap["Info"].toString()));
            refPurifyingExpLog(nextMap["Step"].toInt(),"进行中");
            QMLSignal::I().emitRefExperimentLog(StaticProperties::currentStep);     // 发信号通知前端
        }
        else
        {
            StaticProperties::expStep++;
            run();
        }
    }
    else if(map["Type"]=="2")//只有纯化有跳过
    {
        StaticProperties::expLogList[3][map["Step"].toInt()]["Status"]="跳过";
        StaticProperties::expLogList[3][map["Step"].toInt()]["FinishTime"]=CommonHelper::Common().GetTimeStr();
        StaticProperties::expLogList[3][map["Step"].toInt()]["Time"]="0";

        sql=QString("Update ReportDetail set status='跳过',FinishTime='%1',Time='0' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%2'").arg(CommonHelper::Common().GetTimeStr(),map["Step"].toString());
        query.exec(sql);

        StaticProperties::expStep++;
        run();
    }
    else if(map["Type"]=="3")//等待
    {
        QMLSignal::I().experimentStatus(5,0,"");
        StaticProperties::isWait=true;
        QMLSignal::I().emitRefExperimentLog(StaticProperties::currentStep);     // 发信号通知前端
        StaticProperties::stepStartTime=QDateTime::currentDateTime();
        if(map["WaitType"]=="1")
        {
            waitStep=map["Info"].toInt();
            StaticProperties::isWaitStep=true;
            stepWaitTimer = new QTimer();
            connect(stepWaitTimer, &QTimer::timeout, this, &ExperimentThread::checkWaitStepStatus);
            stepWaitTimer->start(1000);
        }
        else{
            QTimer::singleShot(map["Info"].toInt()*1000, [this]() {  // 使用 QTimer 的单次定时器，延时 n 秒
                if(StaticProperties::isWaitError){
                    StaticProperties::isWaitError=false;
                    return ;
                }
                StaticProperties::isWait=false;
                QMLSignal::I().experimentStatus(5,1,"");

                QSqlDatabase db = dbHelper::openConnection();
                QSqlQuery query(db);
                StaticProperties::expStep++;

                if(StaticProperties::expStatus==1){
                    run();
                }
                else if(StaticProperties::expStatus==2)
                {
                    QMLSignal::I().experimentStatus(5,1,"");

                    QVariantMap map= StaticProperties::expSendList[StaticProperties::expStep];

                    qint64 msecs = QDateTime::currentDateTime().toMSecsSinceEpoch() - StaticProperties::stepStartTime.toMSecsSinceEpoch();
                    StaticProperties::expLogList[StaticProperties::currentExpModule-1][map["Step"].toInt()]["Status"]="完成";
                    StaticProperties::expLogList[StaticProperties::currentExpModule-1][map["Step"].toInt()]["FinishTime"]=CommonHelper::Common().GetTimeStr();
                    StaticProperties::expLogList[StaticProperties::currentExpModule-1][map["Step"].toInt()]["Time"]=QString::number(msecs);

                    QString sql=QString("Update ReportDetail set status='完成',FinishTime='%1',Time='%2' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%3'").arg(CommonHelper::Common().GetTimeStr(),QString::number(msecs),map["Step"].toString());
                    query.exec(sql);

                    StaticProperties::expStatus=1;
                    sql=QString("Update ExperimentInfo set expStep='%1'").arg(QString::number(StaticProperties::expStep));
                    query.exec(sql);
                    QMLSignal::I().emitRefExperimentLog(StaticProperties::currentStep);
                }
            });
        }
    }
    else if(map["Type"]=="4")//检测器
    {
        QString info=map["Info"].toString();
        if(info=="手动"){
//            StaticProperties::expStep++;
            QMLSignal::I().experimentStatus(3,2,"");
            QMLSignal::I().emitRefExperimentLog(StaticProperties::currentStep);     // 发信号通知前端
        }
        else{
            QStringList list=info.split(",");
            StaticProperties::dataThreshold=list[1].toDouble();
            StaticProperties::dataThresholdType=list[0];

            StaticProperties::isProductTesting=true;

            StaticProperties::expStep++;
            sql=QString("Update ExperimentInfo set expStep='%1',dataThreshold='%2',dataThresholdType='%3',isProductTesting='true'").arg(QString::number(StaticProperties::expStep),list[1],list[0]);
            query.exec(sql);

            QMLSignal::I().emitRefExperimentLog(StaticProperties::currentStep);     // 发信号通知前端
        }
    }
    else if(map["Type"]=="5")//非同步联动
    {
        isUnion=true;
        initialUnionStep=map["Step"].toInt();
        StaticProperties::expStep++;

        StaticProperties::currentExpModule=4;
        StaticProperties::expLogList[3][StaticProperties::expStep]["Status"]="进行中";
        sql=QString("Update ReportDetail set status='进行中' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%1'").arg(QString::number(map["Step"].toInt()+1));
        query.exec(sql);
        QMLSignal::I().emitModuleCurrent(StaticProperties::currentExpModule);

        run();
    }
    else if(map["Type"]=="6")//暂停
    {
        QMLSignal::I().emitRefExperimentLog(StaticProperties::currentStep);     // 发信号通知前端

        QVariantMap upMap=StaticProperties::expSendList[StaticProperties::expStep-1];
        QString upSendInfo= upMap["Info"].toString();
        QStringList upList=upSendInfo.split(" ");

        if(upMap["Type"]=="0" && upList[7]=="2D" && upList[8]=="02")
        {
            QMLSignal::I().experimentStatus(3,3,"");
        }
        else{
            QMLSignal::I().experimentStatus(3,1,"");
        }
        if(map["Info"]=="是"){
            QMLSignal::I().sendPauseConfirmation();
        }
        sql=QString("Update ExperimentInfo set expStep='%1'").arg(QString::number(StaticProperties::expStep));
        query.exec(sql);
        //        StaticProperties::expStep++;
    }
    else if(map["Type"]=="7")//检测动作前同步注射器
    {
        StaticProperties::productSyringStartTime=QDateTime::currentDateTime();
        udpClient->ClientSendingData(CommonHelper::Common().GetSendData(map["Info"].toString()));
        QMLSignal::I().emitRefExperimentLog(StaticProperties::currentStep);     // 发信号通知前端
        StaticProperties::productSyringStep=StaticProperties::expStep;
        StaticProperties::expStep++;
        run();
    }
    else if(map["Type"]=="8")//并发联动
    {
        StaticProperties::needRunUnionNumberList.append(map["UnionId"].toInt());
        QString value;
        for(int i=0;i<StaticProperties::needRunUnionNumberList.length();i++){
            value+=QString::number(StaticProperties::needRunUnionNumberList[i])+",";
        }
        value=value.left(value.length()-1);
        sql=QString("Update ExperimentInfo set NeedRunUnionNumberList='%1'").arg(value);
        query.exec(sql);

        StaticProperties:: isConcurrency=true;
        StaticProperties::expLogList[1][StaticProperties::expStep]["Status"]="进行中";
        sql=QString("Update ReportDetail set status='进行中' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%1'").arg(QString::number(map["Step"].toInt()+1));
        query.exec(sql);
        sql="Update ExperimentInfo set IsStepUnion='true'";
        query.exec(sql);
        QMLSignal::I().emitUnionStatus(1);

        StaticProperties::concurrencyStepMap.insert(map["UnionId"].toInt(),StaticProperties::expStep);
        QString mapInfo;
        for (auto it =  StaticProperties::concurrencyStepMap.constBegin(); it !=  StaticProperties::concurrencyStepMap.constEnd(); ++it) {
            mapInfo+=QString("%1.%2,").arg(QString::number(it.key()),QString::number(it.value()));
        }
        mapInfo=mapInfo.left(mapInfo.length()-1);
        sql=QString("Update ExperimentInfo set ConcurrencyStepMap='%1'").arg(mapInfo);
        query.exec(sql);
        concurrencyUnionRun();
        concurrencyStartTime=QDateTime::currentDateTime();

        StaticProperties::expStep++;
        run();
    }
}

void ExperimentThread::concurrencyUnionRun()
{
    UdpClient *udpClient;
    udpClient=UdpClient::getInstance();

    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql;

    if(concurrencyStartTime.isNull()){
        conMsecs=0;
    }
    else{
        conMsecs = QDateTime::currentDateTime().toMSecsSinceEpoch() - concurrencyStartTime.toMSecsSinceEpoch();
    }
    sql=QString("Update ExperimentInfo set StepUnionStep='%1'").arg(QString::number(StaticProperties::expUnionStep));
    query.exec(sql);

    QVariantMap finishmap= StaticProperties::expConcurrencySendList[StaticProperties::expUnionStep-1];

    if(StaticProperties::expUnionStep>1)
    {
        if(StaticProperties::expConcurrencyLogList[finishmap["Step"].toInt()]["Status"]!="故障"){
            StaticProperties::expConcurrencyLogList[finishmap["Step"].toInt()]["Status"]="完成";
            StaticProperties::expConcurrencyLogList[finishmap["Step"].toInt()]["FinishTime"]=CommonHelper::Common().GetTimeStr();
            StaticProperties::expConcurrencyLogList[finishmap["Step"].toInt()]["Time"]=QString::number(conMsecs);

            sql=QString("Update ReportDetail set status='完成',FinishTime='%1',Time='%2' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%3'").arg(CommonHelper::Common().GetTimeStr(),QString::number(msecs),finishmap["Step"].toString());
            query.exec(sql);
        }

        totalconcurrencyMsecs+=conMsecs;
    }

    if(StaticProperties::expUnionStep>StaticProperties::expConcurrencySendList.lastKey()){
        for(int i=0;i<StaticProperties::needRunUnionNumberList.length();i++){
            int step=StaticProperties::concurrencyStepMap[StaticProperties::needRunUnionNumberList[i]];
            if(StaticProperties::expLogList[1].contains(step))
            {
                StaticProperties::expLogList[1][step]["Status"]="完成";
                StaticProperties::expLogList[1][step]["FinishTime"]=CommonHelper::Common().GetTimeStr();
                StaticProperties::expLogList[1][step]["Time"]=QString::number(totalconcurrencyMsecs);

                sql=QString("Update ReportDetail set status='完成',FinishTime='%1',Time='%2' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%3'").arg(CommonHelper::Common().GetTimeStr(),QString::number(msecs),QString::number(step));
                query.exec(sql);
            }
            else if(StaticProperties::expLogList[3].contains(step)){
                StaticProperties::expLogList[3][step]["Status"]="完成";
                StaticProperties::expLogList[3][step]["FinishTime"]=CommonHelper::Common().GetTimeStr();
                StaticProperties::expLogList[3][step]["Time"]=QString::number(totalconcurrencyMsecs);
                sql=QString("Update ReportDetail set status='完成',FinishTime='%1',Time='%2' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%3'").arg(CommonHelper::Common().GetTimeStr(),QString::number(msecs),QString::number(step));
                query.exec(sql);
            }
        }
        StaticProperties::isConcurrency=false;
        QMLSignal::I().emitUnionStatus(0);

        sql="Update ExperimentInfo set IsStepUnion='false'";
        query.exec(sql);
        QMLSignal::I().emitRefExperimentLog(StaticProperties::currentStep);     // 发信号通知前端
        return;
    }

    QVariantMap map= StaticProperties::expConcurrencySendList[StaticProperties::expUnionStep];
    StaticProperties::expConcurrencyLogList[map["Step"].toInt()]["Status"]="进行中";

    if(finishmap["UnionId"].toInt()!=map["UnionId"].toInt())
    {
        int step=StaticProperties::concurrencyStepMap[finishmap["UnionId"].toInt()];

        if(StaticProperties::expLogList[1].contains(step))
        {
            StaticProperties::expLogList[1][step]["Status"]="完成";
            StaticProperties::expLogList[1][step]["FinishTime"]=CommonHelper::Common().GetTimeStr();
            StaticProperties::expLogList[1][step]["Time"]=QString::number(totalconcurrencyMsecs);

            sql=QString("Update ReportDetail set status='完成',FinishTime='%1',Time='%2' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%3'").arg(CommonHelper::Common().GetTimeStr(),QString::number(msecs),QString::number(step));
            query.exec(sql);
        }
        else if(StaticProperties::expLogList[3].contains(step)){
            StaticProperties::expLogList[3][step]["Status"]="完成";
            StaticProperties::expLogList[3][step]["FinishTime"]=CommonHelper::Common().GetTimeStr();
            StaticProperties::expLogList[3][step]["Time"]=QString::number(totalconcurrencyMsecs);
            sql=QString("Update ReportDetail set status='完成',FinishTime='%1',Time='%2' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%3'").arg(CommonHelper::Common().GetTimeStr(),QString::number(msecs),QString::number(step));
            query.exec(sql);
        }

        StaticProperties::needRunUnionNumberList.removeOne(step);
        QString value;
        for(int i=0;i<StaticProperties::needRunUnionNumberList.length();i++){
            value+=QString::number(StaticProperties::needRunUnionNumberList[i])+",";
        }
        sql=QString("Update ExperimentInfo set NeedRunUnionNumberList='%1'").arg(value);
        query.exec(sql);
        totalconcurrencyMsecs=0;
        QMLSignal::I().emitRefExperimentLog(StaticProperties::currentStep);     // 发信号通知前端

    }

    concurrencyStartTime=QDateTime::currentDateTime();


    if(!StaticProperties::needRunUnionNumberList.contains(map["UnionId"].toInt()))
    {
        StaticProperties::isConcurrency=false;
        QMLSignal::I().emitUnionStatus(0);
        sql="Update ExperimentInfo set IsStepUnion='false'";
        query.exec(sql);
        return;
    }


    if(map["Type"]=="0")
    {
        QString sendInfo= map["Info"].toString();
        udpClient->ClientSendingData(CommonHelper::Common().GetSendData(sendInfo));
    }
    else if(map["Type"]=="3")//等待
    {
        StaticProperties::stepStartTime=QDateTime::currentDateTime();

        QTimer::singleShot(map["Info"].toInt()*1000, [this]() {  // 使用 QTimer 的单次定时器，延时 n 秒
            QSqlDatabase db = dbHelper::openConnection();
            QSqlQuery query(db);
            StaticProperties::expUnionStep++;
            concurrencyUnionRun();
        });
    }
    QMLSignal::I().emitRefExperimentLog(StaticProperties::currentStep);     // 发信号通知前端
}

void ExperimentThread::refPurifyingExpLog(int step,QString type,int msecs)
{
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    if(type=="完成")
    {
        if(msecs==0)
        {
            msecs = QDateTime::currentDateTime().toMSecsSinceEpoch() - StaticProperties::stepStartTime.toMSecsSinceEpoch();
        }
        else
        {
            msecs+=QDateTime::currentDateTime().toMSecsSinceEpoch() - StaticProperties::stepStartTime.toMSecsSinceEpoch();
        }

        StaticProperties::expLogList[3][step]["Status"]="完成";
        StaticProperties::expLogList[3][step]["FinishTime"]=CommonHelper::Common().GetTimeStr();
        StaticProperties::expLogList[3][step]["Time"]=QString::number(msecs);

        QString sql=QString("Update ReportDetail set status='完成',FinishTime='%1',Time='%2' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%3'").arg(CommonHelper::Common().GetTimeStr(),QString::number(msecs),QString::number(step));
        query.exec(sql);
    }
    else
    {
        StaticProperties::expLogList[3][step]["Status"]=type;
        QString sql=QString("Update ReportDetail set status='%1' Where ReportSerial=(Select max(ReportSerial) From ReportDetail) and Step='%2'").arg(type,QString::number(step));
        query.exec(sql);
    }
}

/**
 * @brief 常规校验
 * @return 校验结果,空为正常
 */
QString ExperimentThread::routineVerification()
{
    QString info;
    switch (StaticProperties::currentExpType)
    {
    case 0:
        if(StaticProperties::currentExpModule!=4 && StaticProperties::releasseTargetStatus.value("1")!="正常" && StaticProperties::releasseTargetStatus.value("1")!="屏蔽"){
            info+="检测:热室端送靶气泵压力值异常\n";
        }
        else if (StaticProperties::currentExpModule!=4 && StaticProperties::practiceTargetStatus.value("1")!="正常" && StaticProperties::practiceTargetStatus.value("1")!="屏蔽")
        {
            info+="检测:打靶气泵压力值异常\n";
        }
        break;
    case 1:
        if(StaticProperties::releasseTargetStatus.value("1")!="正常" &&StaticProperties::releasseTargetStatus.value("1")!="屏蔽"){
            info+="检测:热室端送靶气泵压力值异常\n";
        }
        break;
    case 2:
        if (StaticProperties::practiceTargetStatus.value("1")!="正常" &&StaticProperties::practiceTargetStatus.value("1")!="屏蔽")
        {
            info+="检测:打靶气泵压力值异常\n";
        }
        break;
    }
    return info;
}

/**
 * @brief 设置实验信息,用于数据恢复
 */
void ExperimentThread::setExpInfo(){
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql="Select * From ExperimentInfo";
    query.exec(sql);
    while (query.next())
    {
        initialUnionStep=query.value("InitialUnionStep").toInt();
        isUnion=query.value("IsUnion").toString().toUpper()=="TRUE";
        unionTime=query.value("UnionTime").toUInt();

        isCircle=query.value("IsCircle").toString().toUpper()=="TRUE";
        circleTime=query.value("CircleTime").toInt();
        StaticProperties::isProductTesting=query.value("IsProductTesting").toString().toUpper()=="TRUE";
        StaticProperties::dataThreshold=query.value("DataThreshold").toDouble();
        StaticProperties::dataThresholdType=query.value("DataThresholdType").toString();
        StaticProperties::isConcurrency=query.value("IsStepUnion").toString().toUpper()=="TRUE";
        StaticProperties::expUnionStep=query.value("StepUnionStep").toInt();

        StaticProperties::needRunUnionNumberList.clear();
        QString number=query.value("NeedRunUnionNumberList").toString();
        if(!number.isNull() &&!number.isEmpty()){
            QStringList numberList=number.split(",");
            for(int i=0;i<numberList.length();i++){
                StaticProperties::needRunUnionNumberList.append(numberList[i].toInt());
            }
        }

        StaticProperties::concurrencyStepMap.clear();
        QString stepMap=query.value("ConcurrencyStepMap").toString();
        if(!stepMap.isNull() &&!stepMap.isEmpty()){
            QStringList stepList=stepMap.split(",");
            for(int i=0;i<stepList.length();i++){
                QStringList stepMapList=stepList[i].split(".");
                StaticProperties::concurrencyStepMap.insert(stepMapList[0].toInt(),stepMapList[1].toInt());
            }
        }
    }
}

/**
 * @brief 特殊步骤校验
 * @return 是否校验通过
 */
bool ExperimentThread::specialStepVerification(){

    //步骤完成校验
    QVariantMap upMap=StaticProperties::expSendList[StaticProperties::expStep-1];
    QString upSendInfo= upMap["Info"].toString();
    QStringList upList=upSendInfo.split(" ");

    if(upList.length()>10){
        if(upMap["Type"]=="0" && upList[7]=="25")
        {
            if(upList[8]=="01"){
                if(StaticProperties::practiceTargetStatus.value("2")!="送靶位置" && StaticProperties::practiceTargetStatus.value("2")!="屏蔽" && StaticProperties::practiceTargetStatus.value("5")!="送靶位置" && StaticProperties::practiceTargetStatus.value("5")!="屏蔽"){
                    QMLSignal::I().emitSendErrorMsg("检测:退靶位置异常","否",QString::number(StaticProperties::currentExpModule),0);
                    return false;
                }
                else if(StaticProperties::practiceTargetStatus.value("2")=="屏蔽"&&StaticProperties::practiceTargetStatus.value("5")!="屏蔽" &&StaticProperties::practiceTargetStatus.value("5")!="送靶位置"){
                    QMLSignal::I().emitSendErrorMsg("检测:退靶位置异常","否",QString::number(StaticProperties::currentExpModule),0);
                    return false;
                }
                else if(StaticProperties::practiceTargetStatus.value("5")=="屏蔽"&&StaticProperties::practiceTargetStatus.value("2")!="屏蔽" &&StaticProperties::practiceTargetStatus.value("2")!="送靶位置"){
                    QMLSignal::I().emitSendErrorMsg("检测:退靶位置异常","否",QString::number(StaticProperties::currentExpModule),0);
                    return false;
                }
            }
            else if(upList[8]=="00"){
                if(StaticProperties::practiceTargetStatus.value("2")!="梭体上靶位置" && StaticProperties::practiceTargetStatus.value("2")!="屏蔽" && StaticProperties::practiceTargetStatus.value("5")!="梭体上靶位置" && StaticProperties::practiceTargetStatus.value("5")!="屏蔽")
                {
                    QMLSignal::I().emitSendErrorMsg("检测:进靶位置异常","否",QString::number(StaticProperties::currentExpModule),0);
                    return false;
                }
                else if(StaticProperties::practiceTargetStatus.value("2")=="屏蔽"&&StaticProperties::practiceTargetStatus.value("5")!="屏蔽" &&StaticProperties::practiceTargetStatus.value("5")!="梭体上靶位置"){
                    QMLSignal::I().emitSendErrorMsg("检测:进靶位置异常","否",QString::number(StaticProperties::currentExpModule),0);
                    return false;
                }
                else if(StaticProperties::practiceTargetStatus.value("5")=="屏蔽"&&StaticProperties::practiceTargetStatus.value("2")!="屏蔽" &&StaticProperties::practiceTargetStatus.value("2")!="梭体上靶位置"){
                    QMLSignal::I().emitSendErrorMsg("检测:进靶位置异常","否",QString::number(StaticProperties::currentExpModule),0);
                    return false;
                }
            }
        }
        if(upMap["Type"]=="0" && upList[7]=="27" && upList[8]=="00"){

            if(StaticProperties::practiceTargetStatus.value("6")!="屏蔽" && StaticProperties::practiceTargetStatus.value("0")!="屏蔽" && StaticProperties::practiceTargetStatus.value("6")!="有" && StaticProperties::practiceTargetStatus.value("0")!="有"){
                QMLSignal::I().emitSendErrorMsg("检测:未检测到靶材罐","否",QString::number(StaticProperties::currentExpModule),0);
                return false;
            }
            else if(StaticProperties::practiceTargetStatus.value("0")=="屏蔽"&&StaticProperties::practiceTargetStatus.value("6")!="屏蔽" &&StaticProperties::practiceTargetStatus.value("6")!="有"){
                QMLSignal::I().emitSendErrorMsg("检测:未检测到靶材罐","否",QString::number(StaticProperties::currentExpModule),0);
                return false;
            }
            else if(StaticProperties::practiceTargetStatus.value("6")=="屏蔽"&&StaticProperties::practiceTargetStatus.value("0")!="屏蔽" &&StaticProperties::practiceTargetStatus.value("0")!="有"){
                QMLSignal::I().emitSendErrorMsg("检测:未检测到靶材罐","否",QString::number(StaticProperties::currentExpModule),0);
                return false;
            }
        }
        if(upMap["Type"]=="0" && upList[7]=="2C")//转靶转液
        {
            CommonHelper::Common().staticUseTime(2,QString::number(msecs/1000));
        }
        if(upMap["Type"]=="0" && upList[7]=="05")//纯化转液
        {
            CommonHelper::Common().staticUseTime(3,QString::number(msecs/1000));
        }
        if(upMap["Type"]=="0" && upList[7]=="22")//真空吸盘
        {
            CommonHelper::Common().staticUseTime(5,"1");
        }
        if(upMap["Type"]=="0" && upList[7]=="2B")//夹爪
        {
            CommonHelper::Common().staticUseTime(6,"1");
        }
        if(upMap["Type"]=="0" && upList[7]=="29")//盖盖
        {
            CommonHelper::Common().staticUseTime(7,"1");
        }
        if(upMap["Type"]=="0" && upList[7]=="29" && upList[8]=="01")
        {
            if(StaticProperties::shiftingTargetStatus.value("2")!="关闭" && StaticProperties::shiftingTargetStatus.value("2")!="屏蔽"){
                QMLSignal::I().emitSendErrorMsg("检测:关盖失败","否",QString::number(StaticProperties::currentExpModule),0);
                return false;
            }
        }
    }

    //步骤执行校验
    QVariantMap map=StaticProperties::expSendList[StaticProperties::expStep];
    QString sendInfo= map["Info"].toString();
    QStringList list=sendInfo.split(" ");

    if(list.length()>10){
        if(CommCommand::I().analysisBarrier(sendInfo)=="打开挡板" &&StaticProperties::releasseTargetStatus.value("0")=="无")
        {
            QMLSignal::I().emitSendErrorMsg("检测:未检测到靶材罐","否",QString::number(StaticProperties::currentExpModule),0);
            return false;
        }
        else if(list[7]=="21" && StaticProperties::practiceTargetStatus[0]=="有")
        {
            QMLSignal::I().emitSendErrorMsg("检测:打靶模块检测到靶材罐,无法继续执行","否",QString::number(StaticProperties::currentExpModule),0);
            return false;
        }
        else if(StaticProperties::currentExpModule==1 && CommCommand::I().analysisBarrier(sendInfo)=="遮挡挡板" &&StaticProperties::releasseTargetStatus.value("0")=="有")
        {
            QMLSignal::I().emitSendErrorMsg("检测:检测到靶材罐,请检查挡板状态","否",QString::number(StaticProperties::currentExpModule),0);
            return false;
        }
        else if(list[7]=="28" && StaticProperties::releasseTargetStatus[0]=="有")
        {
            QMLSignal::I().emitSendErrorMsg("检测:转靶模块检测到靶材罐,无法继续执行","否",QString::number(StaticProperties::currentExpModule),0);
            return false;
        }
        else if(list[7]=="22" && StaticProperties::releasseTargetStatus[0]=="无"){
            QMLSignal::I().emitSendErrorMsg("检测:未检测到靶材罐","否",QString::number(StaticProperties::currentExpModule),0);
            return false;
        }
        else if(list[7]=="30" && StaticProperties::releasseTargetStatus[0]=="无"){
            QMLSignal::I().emitSendErrorMsg("检测:未检测到靶材罐","否",QString::number(StaticProperties::currentExpModule),0);
            return false;
        }
        else if(list[7]=="29" && StaticProperties::releasseTargetStatus[0]=="无"){
            QMLSignal::I().emitSendErrorMsg("检测:未检测到靶材罐","否",QString::number(StaticProperties::currentExpModule),0);
            return false;
        }
        else if(list[7]=="2A" && list[8]=="00")//取靶
        {
            if(StaticProperties::shiftingTargetStatus.value("2")!="打开" &&StaticProperties::shiftingTargetStatus.value("2")!="屏蔽")//开盖失败
            {
                QMLSignal::I().emitSendErrorMsg("检测:开盖失败","否",QString::number(StaticProperties::currentExpModule),0);
                return false;
            }
        }
    }

    return true;
}

/**
 * @brief 特殊步骤处理
 */
void ExperimentThread::specialStepExecute()
{
    UdpClient *udpClient;
    udpClient=UdpClient::getInstance();


    //步骤执行校验
    QVariantMap map=StaticProperties::expSendList[StaticProperties::expStep];
    QString sendInfo= map["Info"].toString();
    QStringList list=sendInfo.split(" ");
    if(list.length()>10){
        if(list[7]=="2B"&& list[8]=="01" && StaticProperties::currentExpModule!=1)//夹爪松开前 发送盖盖运动到初始位置指令
        {
            QString info=CommCommand::I().getOpenTheLid("0","初始");
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(info));
            AnimationParseHEX::I().parse(info.split(" "),0);
            thread()->sleep(1);
        }
        if(list[7]=="28")
        {
            QString info=CommCommand::I().getOpenTheLid("0","移动");
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(info));
            AnimationParseHEX::I().parse(info.split(" "),0);

            thread()->sleep(2);

            info=CommCommand::I().getBarrier("0","打开");
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(info));
            AnimationParseHEX::I().parse(info.split(" "),0);

            thread()->sleep(3);
        }
    }
}

void ExperimentThread::checkWaitStepStatus(){
    if(StaticProperties::isWaitStep){
        if(StaticProperties::expLogList[StaticProperties::currentExpModule-1][waitStep]["Status"]=="完成"){
            StaticProperties::isWaitStep=false;
            StaticProperties::isWait=false;
            QMLSignal::I().experimentStatus(5,1,"");
            StaticProperties::expStep++;
            if (stepWaitTimer && stepWaitTimer->isActive()) {
                stepWaitTimer->stop();
            }
            run();
        }
    }
    else{
        if (stepWaitTimer && stepWaitTimer->isActive()) {
            stepWaitTimer->stop();
        }
    }
}
